﻿using Servo_Tool.entity;
using Servo_Tool.cache;
using Servo_Tool.constant;
using Servo_Tool.domain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Servo_Tool.handler
{
    public class JudgeHandler
    {
        private readonly string unitNo;

        public event Action<string, string, string> ShowMessageUpdated;
        private readonly WriteHandler writeHandler;

        public JudgeHandler(string unitNo, WriteHandler writeHandler)
        {
            this.unitNo = unitNo;
            this.writeHandler = writeHandler;
        }

        /// <summary>
        /// 监听所有item_event_dict缓存中的事件
        /// </summary>
        /// <param name="readNo"></param>
        public void JudgeEventByCache()
        {
            //判断item_event_dict是否有事件可判断
            if (GlobalCachePool.item_event_dict.Count > 0)
            {
                //获取所有itemNo
                foreach (string itemNo in GlobalCachePool.item_event_dict.Keys)
                {
                    //ShowMessage("0", $"尝试判定信号{itemNo}的事件!");

                    JudgeEventByItem(itemNo);
                }
            }
        }

        public void JudgeEventByItem(string itemNo)
        {
            if (string.IsNullOrEmpty(itemNo))
            {
                return;
            }
            //根据itemNo获取其事件链
            if (GlobalCachePool.links_event_dict.TryGetValue(itemNo, out List<EquationLinks_EVENT> links))
            {
                if (links == null || links.Count == 0)
                {
                    return;
                }
            }
            bool result = JudgeEventByLinks(links);
            if (result)
            {
                writeHandler.WriteByItemNo(itemNo);
            }
        }

        public bool JudgeEventByLinks(List<EquationLinks_EVENT> links)
        {
            if (links == null)
            {
                return false;
            }
            bool flag = true;
            //eventLinks可能包含多层触发链,层与层之间是或的关系,只要有一层触发成功,则认为事件触发成功

            foreach (EquationLinks_EVENT link in links)
            {
                List<Equation_EVENT> equations = link.EQUATIONS;
                foreach (Equation_EVENT equation in equations)
                {
                    if (!JudgeEventByEquation(equation))
                    {
                        flag = false;
                        break;
                    }
                }
                //如果当前层级都成功则事件判定成功(否则继续下一层判定)
                if (flag)
                {
                    break;
                }
            }
            return flag;
        }

        public bool JudgeEventByEquation(Equation_EVENT equation)
        {
            if (equation == null)
            {
                return false;
            }
            string symbol = equation.SYMBOL;
            string leftPrefix = equation.LEFT_PREFIX;
            string leftMark = equation.LEFT_MARK;
            string rigthtPrefix = equation.RIGHT_PREFIX;
            string rightMark = equation.RIGHT_MARK;
            //ShowMessage("0", $"尝试判定[{leftPrefix}].{leftMark}{symbol}[{rigthtPrefix}].{rightMark}");
            string leftValue = GetTargetItemValue(leftPrefix, leftMark);
            string rightValue = GetTargetItemValue(rigthtPrefix, rightMark);

            if (SymbolConstants.SYMBOL_EQUAL.Equals(symbol))
            {
                //符号为=,则两者值相等=>true
                if (leftValue.Equals(rightValue))
                {
                    return true;
                }
            }
            else if (SymbolConstants.SYMBOL_NO_EQUAL.Equals(symbol))
            {
                //符号为<>,则则两者值不等=>true
                if (!leftValue.Equals(rightValue))
                {
                    return true;
                }
            }
            else
            {
                //不支持的符号
            }
            return false;
        }

        public string GetTargetItemValue(string prefix, string itemNo)
        {
            string value = "";
            //从PLC_ITEM中获取值
            if (SymbolConstants.FLAG_PLC.Equals(prefix))
            {
                if (GlobalCachePool.single_plcItem_dict.TryGetValue(itemNo, out PlcItemEntity item))
                {
                    value = item.ITEM_VALUE;
                }
            }
            else if (SymbolConstants.FLAG_MEM.Equals(prefix))
            {
                if (GlobalCachePool.single_memItem_dict.TryGetValue(itemNo, out MemItemEntity item))
                {
                    value = item.ITEM_VALUE;
                }
            }
            else
            {
                value = itemNo;
            }

            return value;
        }
        public void ShowMessage(string code, string msg)
        {
            ShowMessageUpdated?.Invoke(unitNo, code, msg);
        }
    }
}
